package org.upida.impl;

import java.beans.PropertyDescriptor;

import org.upida.Dtobase;
import org.upida.IParser;

/**
 * represents Domain object Property metadata
 */
public class PropertyMeta {
	public enum ClassType { Class, CustomType, Collection, CustomTypeCollection, Value }

	private PropertyDescriptor descriptor;
	private String name;
	private Class<?> propertyClass;
	private ClassType propertyClassType;
	private IParser parser;
	private Class<?> nestedGenericClass;
	private byte dtoLevel;
	private byte dtoNestedLevel;
	private boolean dtoCustomType;
	private boolean dtoDynamic;
	private boolean validDto;

	/**
	 * initializes a new instance of the PropertyMeta class
	 * @param descriptor
	 * @throws RuntimeException
	 */
	public PropertyMeta(PropertyDescriptor descriptor) throws RuntimeException {
		this.descriptor = descriptor;
		this.name = descriptor.getName();
		this.propertyClass = descriptor.getPropertyType();
	}

	/**
	 * gets property name
	 */
	public String getName()											{ return this.name; }

	public Class<?> getPropertyClass()								{ return this.propertyClass; }

	public ClassType getPropertyClassType()							{ return this.propertyClassType; }
	public void setPropertyClassType(ClassType value)				{ this.propertyClassType = value; }

	public Class<?> getNestedGenericClass()							{ return this.nestedGenericClass; }
	public void setNestedGenericClass(Class<?> value)				{ this.nestedGenericClass = value; }

	public byte getDtoLevel()										{ return this.dtoLevel; }
	public void setDtoLevel(byte value)								{ this.dtoLevel = value; }

	public byte getDtoNestedLevel()									{ return this.dtoNestedLevel; }
	public void setDtoNestedLevel(byte value)						{ this.dtoNestedLevel = value; }

	public boolean isDtoCustomType()								{ return this.dtoCustomType; }
	public void setDtoCustomType(boolean value)						{ this.dtoCustomType = value; }

	public boolean isDtoDynamic()									{ return this.dtoDynamic; }
	public void setDtoDynamic(boolean value)						{ this.dtoDynamic = value; }

	public IParser getParser()										{ return this.parser; }
	public void setParser(IParser value)							{ this.parser = value; }

	/**
	 * returns true is property is valid DTO
	 */
	public boolean isValid()										{ return this.validDto; }
	public void setValid(boolean value)								{ this.validDto = value; }

	public boolean hasLevel(byte level) {
		return this.dtoLevel <= level;
	}

	public boolean isAssigned(Dtobase target) {
		return target.isFieldAssigned(this.descriptor.getName());
	}

	public void write(Dtobase target, Object value) throws Exception {
		this.descriptor.getWriteMethod().invoke(target, value);
	}

	public Object read(Dtobase target) throws Exception {
		return this.descriptor.getReadMethod().invoke(target);
	}
}